package com.globallogic.jira.gadget.utils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.apache.log4j.Logger;

import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.config.SubTaskManager;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.link.IssueLinkManager;
import com.atlassian.jira.issue.search.SearchException;
import com.atlassian.jira.issue.search.SearchResults;
import com.atlassian.jira.jql.builder.JqlQueryBuilder;
import com.atlassian.jira.project.Project;
import com.atlassian.jira.web.bean.PagerFilter;
import com.atlassian.query.Query;

/**
 * @author anton.pereverziev
 * @author yegor.chumakov
 *         <p/>
 *         A utility class for convenient retrieving projects or issues.
 */
public class Search {

	private static final Logger log = Logger.getLogger(Search.class);
	private static final ComponentManager cm = ComponentManager.getInstance();

	@SuppressWarnings("deprecation")
	public static List<Object> getIssuesFromProject(final Long pid,
			final String issueType, final String fixVersion,
			final boolean includeOrphans, final boolean includeSubtasks)
			throws SearchException {

		final List<Object> result = new ArrayList<Object>(2);

		final JqlQueryBuilder builder = JqlQueryBuilder.newBuilder();
		builder.where().project(pid).and().issueType(issueType);

		if (fixVersion != null) {
			if (fixVersion.equals("NULL")) {
				builder.where().and().fixVersion().eqEmpty();// addEmptyCondition("fixVersion");
			} else if (!fixVersion.equals("All")) {
				builder.where().and().fixVersion(fixVersion);
			}
		}

		final Query query = builder.buildQuery();

		log.debug("\n\tQuerry: " + query);
		SearchResults results = null;

		results = cm.getSearchService().search(
				cm.getJiraAuthenticationContext().getUser(), query,
				PagerFilter.getUnlimitedFilter());

		log.debug("\n\tFound issues: " + results.getTotal());

		final List<Issue> roots = new LinkedList<Issue>();

		final Comparator<Issue> asc = new Comparator<Issue>() {
			@Override
			public int compare(final Issue i1, final Issue i2) {
				return i1.getKey().compareTo(i2.getKey());
			}
		};
		final Set<Issue> notIncluded = new TreeSet<Issue>(asc);

		final IssueLinkManager issueLinkManager = ComponentManager
				.getInstance().getIssueLinkManager();

		final SubTaskManager subTaskManager = ComponentManager.getInstance()
				.getSubTaskManager();

		for (final Issue issue : results.getIssues()) {

			if (includeSubtasks) {
				if ((subTaskManager.getSubTaskIssueLinks(issue.getId()).size() != 0 || (issueLinkManager
						.getInwardLinks(issue.getId()).size() != 0 && issueLinkManager
						.getOutwardLinks(issue.getId()).size() == 0)))
					roots.add(issue);
				else
					notIncluded.add(issue);
			} else if (issueLinkManager.getInwardLinks(issue.getId()).size() != 0
					&& issueLinkManager.getOutwardLinks(issue.getId()).size() == 0)
				roots.add(issue);
			else
				notIncluded.add(issue);
		}

		result.add(roots);
		result.add(notIncluded);
		return result;
	}

	public static Project getProject(final Long pid) throws SearchException {
		return cm.getProjectManager().getProjectObj(pid);
	}

	public static Project getProject(final String key) throws SearchException {
		return cm.getProjectManager().getProjectObjByKey(key);
	}
}
